Skip to content

Added invitation CRUD#128

Merged
jleung40 merged 2 commits intomainfrom
BE_Invitation_Crud
Feb 13, 2026
Merged

Added invitation CRUD#128
jleung40 merged 2 commits intomainfrom
BE_Invitation_Crud

Conversation

@jleung40
Copy link
Contributor

@jleung40 jleung40 commented Feb 10, 2026

Description

Created the POST /trips/:id/invites and POST /trip-invites/:code/join. Notably, this differs from the original ticket instructions of creating a POST /trips/invites/:code/join endpoint. This is made as /trip-invites, since /trips/invites/:code/join was causing fiber to pick up the /invites part of the endpoint as an ID. Anyways, for the invite link url system to work, an env variable for APP_PUBLIC_URL needs to be set, as it's used in trips.go

How has this been tested?

Added tests in invite_tests.go

Checklist

  • I have self-reviewed my code for readability, maintainability, performance, and added comments/documentation where necessary.
  • New and existing tests pass locally with my changes.
  • I have followed the project's coding standards and best practices.

User-Visible Changes

  • Two new endpoints for trip invitation system: POST /trips/{tripID}/invites creates shareable invites with optional custom expiration; POST /trip-invites/{code}/join allows users to join trips via invite codes.
  • Invites support expiration (7-day default) and revocation; expired or revoked invites return HTTP 400 with descriptive error messages.
  • Invite join URL automatically populated in responses when APP_PUBLIC_URL environment variable is configured.
  • Idempotent join behavior—consecutive join attempts from the same user return existing membership without duplication.

Changes by Category

Features

  • Trip invitation CRUD operations with unique code generation and validation.
  • Invite lifecycle management: creation, expiration, and revocation.
  • Race-condition handling for concurrent join attempts.

Infra

  • New trip_invites database table with indexes on trip_id, code, and created_by; cascading deletes from trips and users.
  • TripInviteRepository layer implementing Create, FindByID, and FindByCode operations.
  • Database migration: 20260205035655_create_trip_invite.sql.

Testing

  • Comprehensive test file invites_test.go covering invite creation, successful join, invalid/expired/revoked invites, and authentication.

Documentation

  • Swagger/OpenAPI definitions updated with CreateTripInviteRequest and TripInviteAPIResponse models.
  • Two new API operations documented in docs.go, swagger.json, and swagger.yaml.

Author Contribution

Category Added Removed
Controllers 91 0
Services 75 0
Models 36 0
Repository 66 0
Routes 4 0
Migrations 24 0
Tests 181 0
Documentation 419 0
Other 1 8
Total 897 8

Sequence Flow: Invite Join Operation

User                          Controller              Service              Repository
  |                               |                       |                     |
  +---POST /trip-invites/:code--->|                       |                     |
  |                               |--JoinTripByInviteCode->|                     |
  |                               |                       |---FindByCode------->|
  |                               |                       |<--TripInvite--------|
  |                               |                (validate expiry/revoked)   |
  |                               |                (check existing membership) |
  |                               |---Create Membership--->|                    |
  |                               |<--Membership-----------|                    |
  |<--201 Membership Returned------|                       |                    |

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

📝 Walkthrough

Walkthrough

Adds a trip-invite feature: database migration, TripInvite model and repo, service logic to create and join invites (with code generation, expiry, revocation, and concurrency handling), controller endpoints and routes, OpenAPI docs, and end-to-end tests for invite workflows.

Changes

Cohort / File(s) Summary
Database Schema
backend/internal/migrations/20260205035655_create_trip_invite.sql
Creates trip_invites table with id, trip_id, created_by, code, expires_at, is_revoked, created_at and indexes on trip_id, code, created_by; foreign keys cascade on delete.
Data Models
backend/internal/models/trip_invites.go
Adds TripInvite, CreateTripInviteRequest, and TripInviteAPIResponse types for DB model, request validation, and API response (includes optional join_url).
Repository Layer
backend/internal/repository/trip_invite.go, backend/internal/repository/repository.go
Introduces TripInviteRepository with Create, FindByID, FindByCode; integrates it into the main Repository. Implements Bun-based repo with ErrNotFound mapping.
Trip Invite Creation
backend/internal/services/trips.go, backend/internal/controllers/trips.go, backend/internal/server/routers/trips.go
Adds CreateTripInvite service and controller: generates URL-safe codes, enforces expiry, retries on duplicate codes, persists invites, composes join URL from APP_PUBLIC_URL, and exposes POST /api/v1/trips/{tripID}/invites.
Trip Invite Joining
backend/internal/services/membership.go, backend/internal/controllers/membership.go, backend/internal/server/routers/membership.go
Adds JoinTripByInviteCode service and controller: validates invite code, checks expiry/revocation, returns existing membership if present, creates membership otherwise with race-condition handling; exposes POST /api/v1/trip-invites/{code}/join.
Integration Tests
backend/internal/tests/invites_test.go
Adds end-to-end tests covering invite creation, successful join, idempotent joins, invalid code, expired/revoked invites, and unauthenticated access.
Docs / OpenAPI
backend/docs/docs.go, backend/docs/swagger.yaml, backend/docs/swagger.json
Adds OpenAPI operations and models for create invite and join-by-code endpoints plus new models for CreateTripInviteRequest and TripInviteAPIResponse.
Minor
backend/internal/tests/mocks/mock_S3PresignClient.go
Removes explicit import alias for AWS v4 signer package; no behavioral change.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as MembershipController
    participant Service as MembershipService
    participant InviteRepo as TripInviteRepository
    participant MemberRepo as MembershipRepository
    participant DB

    Client->>Controller: POST /api/v1/trip-invites/{code}/join
    Controller->>Service: JoinTripByInviteCode(userID, code)
    Service->>InviteRepo: FindByCode(code)
    InviteRepo->>DB: SELECT ... WHERE code = ?
    DB-->>InviteRepo: invite row / no rows
    InviteRepo-->>Service: invite / not found
    alt invite invalid/expired/revoked
        Service-->>Controller: return 400
    else invite valid
        Service->>MemberRepo: Find membership by (trip_id,user_id)
        MemberRepo->>DB: SELECT membership...
        DB-->>MemberRepo: existing membership / no rows
        alt already member
            MemberRepo-->>Service: existing membership
            Service-->>Controller: return 201 existing membership
        else not member
            Service->>MemberRepo: Create membership (insert)
            MemberRepo->>DB: INSERT membership...
            DB-->>MemberRepo: success / unique-violation
            alt unique-violation (race)
                MemberRepo->>DB: SELECT existing membership...
                DB-->>MemberRepo: existing membership
                MemberRepo-->>Service: existing membership
            end
            Service-->>Controller: return 201 new membership
        end
    end
    Controller-->>Client: 201 / 400 / 401
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • [BE]: Invitation CRUD #88 — Implements the Trip Invite feature (DB, models, repos, services, controllers, routes, tests) matching this PR's objectives.

Possibly related PRs

Poem

New invites set sails across the map,
Codes whispered softly, a secret tap,
Expiry clocks watch the open door,
Two joins collide and race no more,
Trips gather friends to explore.

🚥 Pre-merge checks | ✅ 1 | ❌ 3
❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Added invitation CRUD' is vague and does not accurately reflect the changes. The PR implements two specific endpoints for creating and joining trip invites, not a complete CRUD system. Use a more specific title such as 'Add trip invite endpoints for creation and joining via code' to clearly convey the primary changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (11 files):

⚔️ backend/docs/docs.go (content)
⚔️ backend/docs/swagger.json (content)
⚔️ backend/docs/swagger.yaml (content)
⚔️ backend/internal/controllers/membership.go (content)
⚔️ backend/internal/controllers/trips.go (content)
⚔️ backend/internal/repository/repository.go (content)
⚔️ backend/internal/server/routers/membership.go (content)
⚔️ backend/internal/server/routers/trips.go (content)
⚔️ backend/internal/services/membership.go (content)
⚔️ backend/internal/services/trips.go (content)
⚔️ backend/internal/tests/mocks/mock_S3PresignClient.go (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BE_Invitation_Crud
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch BE_Invitation_Crud
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

No actionable comments were generated in the recent review. 🎉

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/internal/repository/repository.go (1)

23-34: 🧹 Nitpick | 🔵 Trivial

Minor style inconsistency in repository initialization.

Other repositories are initialized with direct struct literals (e.g., &userRepository{db: db}), while TripInvite uses a constructor function. This works correctly but creates a minor inconsistency. Consider aligning with the existing pattern for uniformity, or refactoring all repositories to use constructor functions for consistency.

🤖 Fix all issues with AI agents
In `@backend/internal/controllers/trips.go`:
- Around line 219-224: Don't ignore the error from c.BodyParser when parsing
CreateTripInviteRequest; instead, first check the raw request body via c.Body()
(or len(c.Body()) == 0) and only skip parsing for an empty body, otherwise call
c.BodyParser(&req) and if it returns an error return a 400/validation error
(rather than discarding it). Update the block around
BodyParser/validators.Validate so that for non-empty bodies a parse error is
propagated (e.g., return a fiber 400 with "invalid JSON") and only allow silent
defaulting when the body is truly empty before calling validators.Validate with
ctrl.validator.

In `@backend/internal/migrations/20260205035655_create_trip_invite.sql`:
- Around line 7-14: Remove the redundant non-unique index creation for the
`code` column: delete the `CREATE INDEX idx_trip_invites_code ON
trip_invites(code);` statement (the `code TEXT NOT NULL UNIQUE` already creates
a unique index) and update the down migration so it no longer tries to DROP
`idx_trip_invites_code` (or remove any DROP INDEX for that name) to keep up/down
symmetric; leave the `idx_trip_invites_trip_id` index and the `code` UNIQUE
constraint intact.

In `@backend/internal/models/trip_invites.go`:
- Line 15: The struct field ExpiresAt on the trip invite model uses
contradictory bun tags `nullzero` and `notnull`; remove the `nullzero` tag so
the bun tag becomes `notnull` (and any other intended options like `expires_at`)
to ensure the column is required. Locate the ExpiresAt field in the trip invite
model (symbol ExpiresAt in trip_invites.go), delete `nullzero` from its struct
tag, run tests and any schema/migration checks to ensure the DB column remains
non-nullable.

In `@backend/internal/services/membership.go`:
- Around line 106-122: Extract the duplicated conversion logic into a single
helper, e.g., create a function membershipFromDB(m
*models.MembershipDatabaseResponse) *models.Membership that maps UserID, TripID,
IsAdmin, BudgetMin, BudgetMax, Availability, CreatedAt and UpdatedAt; then
replace the inline conversions in methods that call s.Membership.Find and
AddMember (the blocks that build a models.Membership from
existingMembership/newMembership) to call membershipFromDB(existingMembership)
(or membershipFromDB(newMembership)) instead.

In `@backend/internal/services/trips.go`:
- Around line 265-271: The generateInviteCode function currently uses 6 random
bytes (48 bits); add a brief comment above generateInviteCode documenting the
approximate collision probability (2^48 possible codes ≈ 281 trillion
combinations) and noting the single-retry behavior in the invite-creation path
(the duplicate-check/retry logic that follows) is based on that low probability;
alternatively, if you expect high-volumes, increase entropy by changing the
function to use 8 bytes (64 bits) and update any dependent code/comments
accordingly (keep function name generateInviteCode and ensure callers that
validate duplicates remain compatible).
- Around line 296-306: The retry path after detecting errs.ErrDuplicate must
handle errors from generateInviteCode instead of discarding them: in the block
around s.TripInvite.Create and generateInviteCode, capture the error returned by
generateInviteCode, and if non-nil return it immediately (do not overwrite
invite.Code with an invalid value); only assign invite.Code and call
s.TripInvite.Create again when generateInviteCode succeeds. Ensure the
subsequent err checks still return on failure and reference the existing symbols
s.TripInvite.Create, generateInviteCode, invite.Code, created.
- Around line 308-314: The code currently calls os.Getenv("APP_PUBLIC_URL")
inside CreateTripInvite leading to repeated syscalls; add a field (e.g.,
appPublicURL string) to the service struct in the constructor or a config struct
so the value is read once, initialize s.appPublicURL when the service is
created, and replace the getenv call in CreateTripInvite with s.appPublicURL;
ensure you still trim trailing slashes and build the joinURL using created.Code
(and update any tests to inject the appPublicURL via the service
constructor/config).

In `@backend/internal/tests/invites_test.go`:
- Around line 95-129: The test inserts a TripInvite directly using
db.NewInsert() which can leave state behind; add a t.Cleanup callback
immediately after the insert that deletes the inserted record (use
db.NewDelete().Model for models.TripInvite and filter by invite.ID) to ensure
isolation and prevent flakiness; place the cleanup right after the call that
sets invite (i.e., after NewInsert().Model(invite).Exec) so the inserted invite
is removed after the test finishes.

Comment on lines +7 to +14
code TEXT NOT NULL UNIQUE,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
is_revoked BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now()
);

CREATE INDEX idx_trip_invites_trip_id ON trip_invites(trip_id);
CREATE INDEX idx_trip_invites_code ON trip_invites(code);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Index on code is redundant with UNIQUE constraint.

Line 7 declares code TEXT NOT NULL UNIQUE, which automatically creates a unique index. Line 14 creates an additional index idx_trip_invites_code on the same column. This duplicate index wastes storage and slows writes.

Remove redundant index
 CREATE INDEX idx_trip_invites_trip_id ON trip_invites(trip_id);
-CREATE INDEX idx_trip_invites_code ON trip_invites(code);
 CREATE INDEX idx_trip_invites_created_by ON trip_invites(created_by);

Also update the down migration:

 DROP INDEX IF EXISTS idx_trip_invites_created_by;
-DROP INDEX IF EXISTS idx_trip_invites_code;
 DROP INDEX IF EXISTS idx_trip_invites_trip_id;
🤖 Prompt for AI Agents
In `@backend/internal/migrations/20260205035655_create_trip_invite.sql` around
lines 7 - 14, Remove the redundant non-unique index creation for the `code`
column: delete the `CREATE INDEX idx_trip_invites_code ON trip_invites(code);`
statement (the `code TEXT NOT NULL UNIQUE` already creates a unique index) and
update the down migration so it no longer tries to DROP `idx_trip_invites_code`
(or remove any DROP INDEX for that name) to keep up/down symmetric; leave the
`idx_trip_invites_trip_id` index and the `code` UNIQUE constraint intact.

TripID uuid.UUID `bun:"trip_id,type:uuid,notnull" json:"trip_id"`
CreatedBy uuid.UUID `bun:"created_by,type:uuid,notnull" json:"created_by"`
Code string `bun:"code,notnull" json:"code"`
ExpiresAt time.Time `bun:"expires_at,nullzero,notnull" json:"expires_at"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Contradictory bun tags: nullzero with notnull on expires_at.

The nullzero tag instructs bun to convert Go's zero time.Time to SQL NULL, while notnull declares the column cannot be NULL. If ExpiresAt is ever unset (zero value), the insert will fail at the database level. The service currently always sets this field, but this tag combination is error-prone for future maintainers.

Consider removing nullzero since ExpiresAt is required:

Proposed fix
-	ExpiresAt time.Time `bun:"expires_at,nullzero,notnull" json:"expires_at"`
+	ExpiresAt time.Time `bun:"expires_at,notnull" json:"expires_at"`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ExpiresAt time.Time `bun:"expires_at,nullzero,notnull" json:"expires_at"`
ExpiresAt time.Time `bun:"expires_at,notnull" json:"expires_at"`
🤖 Prompt for AI Agents
In `@backend/internal/models/trip_invites.go` at line 15, The struct field
ExpiresAt on the trip invite model uses contradictory bun tags `nullzero` and
`notnull`; remove the `nullzero` tag so the bun tag becomes `notnull` (and any
other intended options like `expires_at`) to ensure the column is required.
Locate the ExpiresAt field in the trip invite model (symbol ExpiresAt in
trip_invites.go), delete `nullzero` from its struct tag, run tests and any
schema/migration checks to ensure the DB column remains non-nullable.

Comment on lines +106 to +122
// If already a member, return existing membership.
existingMembership, err := s.Membership.Find(ctx, userID, invite.TripID)
if err == nil {
return &models.Membership{
UserID: existingMembership.UserID,
TripID: existingMembership.TripID,
IsAdmin: existingMembership.IsAdmin,
BudgetMin: existingMembership.BudgetMin,
BudgetMax: existingMembership.BudgetMax,
Availability: existingMembership.Availability,
CreatedAt: existingMembership.CreatedAt,
UpdatedAt: existingMembership.UpdatedAt,
}, nil
}
if !errors.Is(err, errs.ErrNotFound) {
return nil, err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider extracting membership conversion to a helper.

The code that converts MembershipDatabaseResponse to Membership (lines 109-118, 143-152) is duplicated here and also appears in AddMember (lines 62-71). A helper method would reduce repetition.

Optional helper extraction
func toMembership(m *models.MembershipDatabaseResponse) *models.Membership {
	return &models.Membership{
		UserID:       m.UserID,
		TripID:       m.TripID,
		IsAdmin:      m.IsAdmin,
		BudgetMin:    m.BudgetMin,
		BudgetMax:    m.BudgetMax,
		Availability: m.Availability,
		CreatedAt:    m.CreatedAt,
		UpdatedAt:    m.UpdatedAt,
	}
}

Also applies to: 135-155

🤖 Prompt for AI Agents
In `@backend/internal/services/membership.go` around lines 106 - 122, Extract the
duplicated conversion logic into a single helper, e.g., create a function
membershipFromDB(m *models.MembershipDatabaseResponse) *models.Membership that
maps UserID, TripID, IsAdmin, BudgetMin, BudgetMax, Availability, CreatedAt and
UpdatedAt; then replace the inline conversions in methods that call
s.Membership.Find and AddMember (the blocks that build a models.Membership from
existingMembership/newMembership) to call membershipFromDB(existingMembership)
(or membershipFromDB(newMembership)) instead.

Comment on lines +308 to +314
var joinURL *string
baseURL := os.Getenv("APP_PUBLIC_URL")
if baseURL != "" {
trimmed := strings.TrimRight(baseURL, "/")
u := trimmed + "/invites/" + created.Code
joinURL = &u
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Avoid reading environment variable on every request.

os.Getenv("APP_PUBLIC_URL") is called on each invite creation. Inject this value through the service constructor or a config struct to avoid repeated syscalls and improve testability.

Proposed approach
 type TripService struct {
 	*repository.Repository
 	fileService FileServiceInterface
 	publisher   realtime.EventPublisher
+	appPublicURL string
 }

-func NewTripService(repo *repository.Repository, fileService FileServiceInterface, publisher realtime.EventPublisher) TripServiceInterface {
+func NewTripService(repo *repository.Repository, fileService FileServiceInterface, publisher realtime.EventPublisher, appPublicURL string) TripServiceInterface {
 	return &TripService{
 		Repository:  repo,
 		fileService: fileService,
 		publisher:   publisher,
+		appPublicURL: appPublicURL,
 	}
 }

Then use s.appPublicURL instead of os.Getenv("APP_PUBLIC_URL") in CreateTripInvite.

🤖 Prompt for AI Agents
In `@backend/internal/services/trips.go` around lines 308 - 314, The code
currently calls os.Getenv("APP_PUBLIC_URL") inside CreateTripInvite leading to
repeated syscalls; add a field (e.g., appPublicURL string) to the service struct
in the constructor or a config struct so the value is read once, initialize
s.appPublicURL when the service is created, and replace the getenv call in
CreateTripInvite with s.appPublicURL; ensure you still trim trailing slashes and
build the joinURL using created.Code (and update any tests to inject the
appPublicURL via the service constructor/config).

Comment on lines +95 to +129
t.Run("expired invite returns 400", func(t *testing.T) {
app := fakes.GetSharedTestApp()
db := fakes.GetSharedDB()

owner := createUser(t, app)
trip := createTrip(t, app, owner)

code := "expired-" + uuid.NewString()
expired := time.Now().UTC().Add(-1 * time.Hour)

invite := &models.TripInvite{
ID: uuid.New(),
TripID: uuid.MustParse(trip),
CreatedBy: uuid.MustParse(owner),
Code: code,
ExpiresAt: expired,
IsRevoked: false,
CreatedAt: time.Now().UTC(),
}

_, err := db.NewInsert().Model(invite).Exec(context.Background())
require.NoError(t, err)

user := createUser(t, app)

testkit.New(t).
Request(testkit.Request{
App: app,
Route: fmt.Sprintf("/api/v1/trip-invites/%s/join", code),
Method: testkit.POST,
UserID: &user,
}).
AssertStatus(http.StatusBadRequest).
AssertField("message", "invite link has expired")
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider test data cleanup for isolation.

Tests that directly insert data via db.NewInsert() (lines 115 and 151) may leave records in the shared test database. If other tests depend on specific invite counts or codes, this could cause flaky behavior. Consider adding cleanup in a t.Cleanup() callback or using unique code prefixes with a cleanup sweep.

Proposed cleanup pattern
// After inserting the invite
t.Cleanup(func() {
    _, _ = db.NewDelete().Model((*models.TripInvite)(nil)).Where("id = ?", invite.ID).Exec(context.Background())
})
🤖 Prompt for AI Agents
In `@backend/internal/tests/invites_test.go` around lines 95 - 129, The test
inserts a TripInvite directly using db.NewInsert() which can leave state behind;
add a t.Cleanup callback immediately after the insert that deletes the inserted
record (use db.NewDelete().Model for models.TripInvite and filter by invite.ID)
to ensure isolation and prevent flakiness; place the cleanup right after the
call that sets invite (i.e., after NewInsert().Model(invite).Exec) so the
inserted invite is removed after the test finishes.

CreatedAt time.Time `bun:"created_at,nullzero" json:"created_at"`
}

func (TripInvite) TableName() string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove this, i don't think it's being used anywhere

Copy link
Contributor Author

@jleung40 jleung40 Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which thing are you referring to? the created at or tablename()

Copy link
Contributor

@in-mai-space in-mai-space left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GREAT JOB @jleung40 🔥 few small nits and should be good to go!

"context"

v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
Copy link
Contributor

@aahiltn aahiltn Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

damn im not sure why this keeps popping up and disappearing in some prs. must be local linter settings. (no change needed)

@aahiltn
Copy link
Contributor

aahiltn commented Feb 12, 2026

Good call on the endpoint structuring! Sound logic to me. Just fix those nits, and you'll be good to merge my goat J

Copy link
Contributor

@in-mai-space in-mai-space left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀🚀🚀 SHIPPP

@jleung40 jleung40 merged commit 178c961 into main Feb 13, 2026
9 checks passed
@jleung40 jleung40 deleted the BE_Invitation_Crud branch February 13, 2026 01:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants